<?php

class gSessionDatabase extends gKernel implements gSessionStructure {

    /**
     *
     * @var <type>
     */
    private $sessionData = array();
    /**
     *
     * @var <type>
     */
    private $sessionId   = null;
    /**
     *
     * @var <type>
     */
    private $sessionUserhash = null;
    /**
     *
     * @var <type>
     */
    private $database = null;
    /**
     *
     * @var <type>
     */
    private $sessionLifespan = null;
    /**
     *
     * @var <type>
     */
    private $sessionTimeout = null;
    /**
     *
     * @var <type> 
     */
    private $sessionName    =null;

    /**
     *
     * @param <type> $sessionId
     * @param <type> $sessionUserhash
     */
    public function init($sessionId,$sessionUserhash){
        $this->sessionId = $sessionId;
        $this->sessionUserhash = $sessionUserhash;

    }
    /**
     *
     */
    public function start() {
        
        $database = $this->core->get("sessiondb");
        if( $database !="auto" && in_array($database,$this->core->dbo->getConnected())){
            $this->database = $this->core->dbo->getConnection($database);
        } else {
            $this->database = $this->core->getObject("dbo");
        }
        $this->sessionLifespan = $this->core->session->getSessionLifespan();
        $this->sessionTimeout = $this->core->session->getSessionTimeout();
        $this->sessionName = $this->core->session->getSessionName();
        $this->collectgarbage();
        $session = $this->database->select("users_session", "lifetime,usertrace,user_id",
                " where session_id='" . $this->sessionId . "' limit 1 offset 0", _RESULT_ROW);
        $userid = 0;
        if (count($session) == 0){
            $this->database->insert("users_session", array(
                "session_id" => $this->sessionId,
                "created" => date("U"),
                "last_impression" => date("U"),
                "usertrace" => $this->sessionUserhash,
                "user_id"=>0,
                "user_agent" =>$this->core->session->getUserBrowser()
            ));
	} else {
            $userid = (int)$session["user_id"];
            $this->database->update("users_session", " set last_impression='" . date("U") . "',online='1' where session_id='" . $this->sessionId . "'");
            $this->sessionLifespan = $session["lifetime"];
            if( $session["usertrace"]!=$this->sessionUserhash && $userid!=0 ) {
                # session capturing detected
                $this->core->log->write("SESSION: session capturing from other side detected, making new for " . $this->sessionId,_LOG_CRITICAL);
                $this->clear($this->sessionId);
                # Creating new record in session table
                $this->database->insert("users_session", array(
                    "session_id" => $this->sid,
                    "created" => date("U"),
                    "last_impression" => date("U"),
                    "usertrace" => $usertrace,
                    "user_agent" => $this->core->session->getUserBrowser()
                ));
            }
        }
        # clearing for all my last impressions
        setcookie($this->sessionName, $this->sessionId, $this->sessionLifespan, "/");
        $this->read();
        # checking for multi session access
        if( !$this->core->get("multiaccess") && $userid!=0){
            # clearing all previous
            $this->core->dbo->delete("users_session", "where session_id!='" . $this->sessionId . "' and user_id='" . $userid . "'");
        }
        return true;
    }
    /**
     *
     * @return <type>
     */
    public function read(){
        $Query = $this->database->select("users_session_variable", "data", " where session_id='" . $this->sessionId . "' limit 1 offset 0", _RESULT_ROW);
        if (count($Query) == 1 && !empty($Query["data"])){
            $this->sessionData = unserialize($Query["data"]);
        }
        return true;
    }
    /**
     *
     */
    public function write() {
        $query = $this->database->select("users_session_variable", "session_id", " where session_id='" . $this->sessionId . "' limit 1 offset 0");
        $data = serialize($this->sessionData);
        if (count($query) == 1){
            $this->database->update("users_session_variable", " set data='" . $data . "' where session_id='" . $this->sessionId . "'");
        } else {
            $this->database->insert("users_session_variable", array(
            "session_id" => $this->sessionId,
            "data" => $data));
        }
        return true;
    }

    /**
     *
     * @return <type>
     */
    public function close() {
        if ($this->core->get("runmode") == _CONSOLE_RUNMODE){
            return false;
        }
        $this->core->DEBUG("SESSION", "Closing session for " . $this->sessionId);
        $this->write();
        return true;
    }

    /**
     *
     * @param <type> $sessionId
     */
    public function clear($sessionId) {
        $this->database->delete("users_session", " where session_id='".$sessionId."' ");
        $this->database->delete("users_session_variable", " where session_id='".$sessionId. "'");
    }

    /**
     *
     * @return <type>
     */
    public function collectgarbage() {
        # clearing all guests
        $this->database->delete("users_session", " where last_impression<'" . (date("U") - $this->sessionTimeout) . "' and lifetime='0'");
        # clearing by timeout setted lifetime
        $this->database->delete("users_session", "where lifetime!='0' and lifetime<" . date("U"));
        # clearing all data of non-existed sessions
        $this->database->delete("users_session_variable", " where session_id NOT IN (SELECT session_id from users_session)");
        return true;
    }

    /**
     *
     * @param <type> $key
     * @return <type>
     */
    public function get($key) {
        return isset($this->sessionData[$key]) ? $this->sessionData[$key] : false;
    }
    /**
     *
     * @param <type> $key
     * @param <type> $value
     */
    public function set($key,$value=null) {
        $this->sessionData[$key] = $value;
    }
    /**
     *
     * @param <type> $key
     */
    public function delete($key) {
        unset($this->sessionData[$key]);
    }
    /**
     *
     * @param <type> $key
     * @return <type>
     */
    public function exists($key) {
        return isset($this->sessionData[$key]) ? true : false;
    }
    /**
     *
     */
    public function destroy(){
        $this->database->delete("users_session", " where session_id='".$this->sessionId."' ");
        $this->database->delete("users_session_variable", " where session_id='".$this->sessionId."'");
    }
    /**
     *
     * @param <type> $time 
     */
    public function resetlifetime($time) {
        if ($this->core->user->CheckUser()){
            $time = time() + 80000 + $time;
            $this->dbo->update("users_session", "set lifetime='" . $time . "' where session_id='" . $this->sid . "'");
        }
    }

}